package in.muton.edushare.grading.panels.studentGrades;

import in.muton.edushare.EduShareSession;
import in.muton.edushare.processing.objects.CourseDataHandler;
import in.muton.edushare.wicket.models.CayenneModel;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import org.apache.wicket.model.IModel;

import com.edushare.common.dao.academics.grades.EntityLetterGrade;
import com.edushare.common.dao.academics.grades.InternalGrades;
import com.edushare.common.dao.academics.grades.LetterGradeMap;
import com.edushare.common.orm.ORMInterface;
import com.edushare.common.vo.CourseGrade;
import com.edushare.common.vo.CourseInstances;
import com.edushare.common.vo.GradeKey;
import com.edushare.common.vo.GradingItem;
import com.edushare.common.vo.ItemGrade;
import com.edushare.common.vo.Users;

public class GradingUtil implements Serializable {
	private IModel<CourseInstances> courseInst = null;

	public GradingUtil(IModel<CourseInstances> courseInst) {
		this.courseInst = courseInst;
	}

	public static class ItemGradeHelper implements Serializable {
		public IModel<Users> user;
		public double marks = 0.0;
		public String comments = "";
		public IModel<GradingItem> gradingItem;

		private static final long serialVersionUID = 5191493512143485449L;
	}

	public static class CourseGradeHelper implements Serializable {
		public IModel<Users> user;
		public double marks = -1;
		public IModel<CourseInstances> inst;
		public IModel<GradeKey> key;
		public boolean isLetterGrade = false;
		public boolean manualSet = false;
		public String comments = "";
		public String temp = "";

		public void setTemp(String s) {
			manualSet = true;
			this.temp = s;
		}

		private static final long serialVersionUID = 4545214934699772239L;
	}

	public List<ItemGradeHelper> getMarkList(GradingItem item) {
		InternalGrades ig = new InternalGrades(getORM());
		List<ItemGradeHelper> ighList = new ArrayList<ItemGradeHelper>();
		List<Users> userList = new CourseDataHandler(courseInst).getStudents()
				.getUtilList();
		for (Users u : userList) {
			ItemGrade itgr = ig.getStudentMarksItem(u, item);
			ItemGradeHelper igh = new ItemGradeHelper();
			igh.gradingItem = new CayenneModel<GradingItem>(item);
			igh.user = new CayenneModel<Users>(u);
			if (itgr != null) {
				igh.marks = itgr.getMarks();
				igh.comments = itgr.getComments();
			}
			ighList.add(igh);
		}
		return ighList;
	}

	public boolean isValidMarks(double marks, GradingItem item) {
		double max = item.getMaxMarks();
		if (marks > max)
			return false;
		return true;
	}

	public void saveMarks(ItemGradeHelper itgh) {
		InternalGrades ig = new InternalGrades(getORM());
		ig.setStudentCompMarks(itgh.user.getObject(), itgh.gradingItem
				.getObject(), itgh.marks, itgh.comments);
	}

	public CourseGradeHelper getGrades(Users u) {
		InternalGrades ig = new InternalGrades(getORM());
		CourseGrade cg = ig.getStudentCourseGrade(courseInst.getObject(), u);
		CourseGradeHelper cgh = new CourseGradeHelper();
		cgh.inst = courseInst;
		cgh.user = new CayenneModel<Users>(u);
		cgh.isLetterGrade = new EntityLetterGrade(getORM())
				.courseHasGrade(courseInst.getObject());
		if (cg != null) {
			cgh.marks = cg.getMarks();
			cgh.isLetterGrade = cg.getEvaluationType() == CourseGrade.EVAL_GRADE;
			if (cgh.isLetterGrade) {
				cgh.key = new CayenneModel<GradeKey>(cg.getGradeKey());
				cgh.temp = cg.getGradeKey().getGradeAlphabet();
			} else
				cgh.temp = cg.getMarks() + "";
		}
		return cgh;
	}

	public List<CourseGradeHelper> getGrades() {
		List<CourseGradeHelper> cghList = new ArrayList<CourseGradeHelper>();
		List<Users> userList = new CourseDataHandler(courseInst).getStudents()
				.getUtilList();
		for (Users u : userList) {
			CourseGradeHelper cgh = getGrades(u);
			cghList.add(cgh);
		}
		return cghList;
	}

	public boolean isValidKey(String s) {
		LetterGradeMap map = new LetterGradeMap(getORM());
		GradeKey k = map.getGradeKey(s, courseInst.getObject());
		if (k == null)
			return false;
		return true;
	}

	public boolean isMarksOK(double marks) {
		return marks <= 100.0;
	}

	public void saveMarks(CourseGradeHelper cgH) {
		InternalGrades ig = new InternalGrades(getORM());
		LetterGradeMap lgm = new LetterGradeMap(getORM());
		GradeKey key = null;
		if (cgH.isLetterGrade) {
			key = lgm.getGradeKey(cgH.temp, courseInst.getObject());
		} else {
			try {
				cgH.marks = Double.parseDouble(cgH.temp);
			} catch (NumberFormatException e) {
			}
		}
		ig.setCourseGrade(cgH.inst.getObject(), cgH.user.getObject(),
				cgH.comments, key, cgH.marks);
	}

	private ORMInterface getORM() {
		return EduShareSession.get().getSessionORMInterface();
	}

	public List<ItemGradeHelper> getGradesByUser(Users u) {
		List<ItemGradeHelper> ighList = new ArrayList<ItemGradeHelper>();
		List<GradingItem> giList = courseInst.getObject().getGradingItems();
		for (GradingItem gi : giList) {
			ighList.add(getGradesByItemUser(u, gi));
		}
		return ighList;
	}

	public ItemGradeHelper getGradesByItemUser(Users u, GradingItem item) {
		InternalGrades igrade = new InternalGrades(getORM());
		ItemGrade itgr = igrade.getStudentMarksItem(u, item);
		ItemGradeHelper igh = new ItemGradeHelper();
		igh.gradingItem = new CayenneModel<GradingItem>(item);
		igh.user = new CayenneModel<Users>(u);
		if (itgr != null) {
			igh.marks = itgr.getMarks();
			igh.comments = itgr.getComments();
		}
		return igh;
	}

	private static final long serialVersionUID = 7855927340086463540L;
}
